package com.umpay.business.ebankpayment.impl;

import java.util.HashMap;
import java.util.Map;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.umpay.business.ebankpayment.EbankPayBusiness;
import com.umpay.dict.DataDict;
import com.umpay.dict.XmlData;
import com.umpay.dict.retcode.MerBusiEC;
import com.umpay.dto.UMFResponse.Message;
import com.umpay.dto.UMFResponse.Message.Meta;
import com.umpay.dto.merBusi.req.ebankpayment.EbankPayOrderBusiReq;
import com.umpay.dto.merBusi.res.ebankpayment.EbankPayOrderBusiRes;
import com.umpay.entity.Trans;
import com.umpay.exception.BusinessException;
import com.umpay.service.trans.TransService;
import com.umpay.util.StringUtil;
import com.umpay.util.StringUtils;
import com.umpay.utils.BankCodeConvertUtil;
import com.umpay.utils.DES3Util;
import com.umpay.utils.GetSequenceHelper;
import com.umpay.utils.PropertyUtil;
import com.umpay.utils.TableNameHelper;
import com.umpay.utils.TimeUtil;

@Component
public class EbankPayBusinessImpl implements EbankPayBusiness {

	public static final Logger log = LogManager.getLogger(EbankPayBusinessImpl.class);

	
	@Autowired
	private PropertyUtil propertyUtil;
	
	@Autowired
	private GetSequenceHelper getSequenceHelper;
	
//	@Autowired
//	private ConsumeSplitService consumeSplitService;

	
	@Autowired
	private TransService transService;
	
	@Autowired
	private TableNameHelper tableNameHelper;
	
	@Override
	public Message<EbankPayOrderBusiRes> EbankPayOrderBusiness(EbankPayOrderBusiReq ebankPayBusiReq) {

		Map<String,Object> retMap= new HashMap<String,Object>();
		log.info("【网银支付】step1、商户信息校验。。。");
		checkMerInfoAndState(ebankPayBusiReq,retMap);
		
		log.info("【网银支付】step2、(业务处理)商户待结算账户校验。。。");
		checkMerSettleAccState(ebankPayBusiReq,retMap);
		
		log.info("【网银支付】step3、业务产品校验。。。");
		checkMerBproductInfo(ebankPayBusiReq);
		
		log.info("【网银支付】step4、支付产品校验。。。");
		checkMerPproductInfo(ebankPayBusiReq);
		
		log.info("【网银支付】step5、支持的银行列表校验。。。");
		checkSupportBank(ebankPayBusiReq);
		
		log.info("【网银支付】step6、(业务处理)订单校验。。。");
		checkOrder(ebankPayBusiReq,retMap);
		
		log.info("【网银支付】step7、查询手续费。。。");
		queryFee(ebankPayBusiReq,retMap);
		
		log.info("【网银支付】step8、校验分账方手续费是否足够。。。");
		checkSplitFee(ebankPayBusiReq,retMap);
		
		log.info("【网银支付】step9、记录交易表。。。");
		insertTrans(ebankPayBusiReq,retMap);
		
		log.info("【网银支付】step10、响应接入层。。。");
//		resMeta.setRet_code(DataDict.BUSISUCCESS);
//		resMeta.setRet_msg("操作成功");
//		resData.setMerId(StringUtils.trim(ebankPayBusiReq.getMerId()));
//		resData.setRpid(StringUtils.trim(ebankPayBusiReq.getRpid()));
//		resData.setVersion("1.0");
//		resData.setMerTrace(StringUtils.trim(ebankPayBusiReq.getMerTrace()));
//		resData.setTrace(StringUtils.trim(retMap.get(XmlData.TRACE)));
//		resData.setInstId(StringUtils.trim(retMap.get(XmlData.INSTID)));
//
//		resData.setOrderId(StringUtils.trim(retMap.get(XmlData.ORDERID)));
//		resData.setOrderDate(StringUtils.trim(retMap.get(XmlData.ORDERDATE)));
//		resData.setServType(StringUtils.trim(retMap.get(XmlData.BUSIID)));
//		resData.setTradeNo(StringUtils.trim(ebankPayBusiReq.getTradeNo()));
//		resData.setAmount(StringUtils.trim(ebankPayBusiReq.getAmount()));
		//resData.setSettleAmt(StringUtils.trim(Long.valueOf(StringUtils.trim(retMap.get(XmlData.AMOUNT)))-Long.valueOf(StringUtils.trim(retMap.get(XmlData.FEE)))));
		//resData.setMerCheckDate(StringUtils.trim(retMap.get(XmlData.MERCHECKDATE)));
		
//		resMessage.setMeta(resMeta);
//		resMessage.setData(resData);
		return null;
	}

	private void checkSplitFee(EbankPayOrderBusiReq ebankPayBusiReq, Map<String, Object> retMap) {
		
		String comAmtType = StringUtils.trim(retMap.get(XmlData.COMAMTTYPE));
		String orderType = StringUtils.trim(retMap.get(XmlData.ORDERTYPE));
		String busiId = StringUtils.trim(retMap.get(XmlData.BUSIID));
		retMap.put(XmlData.MERID, StringUtils.trim(ebankPayBusiReq.getMerId()));
		if(DataDict.BUSIID_02.equals(busiId)&&(DataDict.ORDER_TYPE_2.equals(orderType) || DataDict.ORDER_TYPE_3.equals(orderType))){//消费
			if(String.valueOf(DataDict.COMAMTTYPE_1).equals(comAmtType)){//手续费从交易现金账户扣除
				log.info("【网银支付】手续费从交易现金账户扣除，需要检验分账方手续费是否足够");
//				consumeSplitService.checkSplitFeeIsEnough(retMap);
			}else if(String.valueOf(DataDict.COMAMTTYPE_2).equals(comAmtType)){
				log.info("【网银支付】手续费从平台手续费账户扣除,无需校验手续费账户。");//手续费账户开于标商端，无法校验。
				//consumeSplitService.checkFeeAccIsEnough(dc);
			}else{
				log.info("【网银支付】未配置手续费！");
				throw new BusinessException(MerBusiEC.COMAMTTYPE_NO_CONF, "未配置手续费！");
			}
		}
		
	}

	private void queryFee(EbankPayOrderBusiReq ebankPayBusiReq, Map<String, Object> retMap) {

		Map<String,String> reqMap = new HashMap<String,String>();
		
		reqMap.put(XmlData.RPID, StringUtils.trim(ebankPayBusiReq.getRpid()));
		reqMap.put(XmlData.MERID, StringUtils.trim(ebankPayBusiReq.getMerId()));
		reqMap.put(XmlData.PPRODUCTID, StringUtils.trim(ebankPayBusiReq.getpProductId()));
		reqMap.put(XmlData.AMOUNT,StringUtils.trim(ebankPayBusiReq.getAmount()));
		reqMap.put(XmlData.BUSIID, DataDict.BUSIID_02);
		reqMap.put(XmlData.ORDERDATE, StringUtil.trim(retMap.get(XmlData.ORDERDATE)));
//		Map<String, Object> feeMap = feeCommonBusiness.getFee(reqMap);
//		if(feeMap!=null&&!StringUtils.isEmpty(StringUtils.trim(feeMap.get(XmlData.FEE)))){
//			retMap.put(XmlData.FEE, StringUtil.trim(feeMap.get(XmlData.FEE)));
//			retMap.put(XmlData.COMAMTTYPE, StringUtil.trim(feeMap.get(XmlData.COMAMTTYPE)));
//		}else{
//			log.info("【网银支付】获取交易费率异常！");
//			throw new BusinessException(MerBusiEC.GET_FEE_ERR,"获取交易费率异常！");
//		}
	}

	private void insertTrans(EbankPayOrderBusiReq ebankPayBusiReq, Map<String, Object> retMap) {

		Trans trans =getInsertTransData(ebankPayBusiReq,retMap);
		transService.insert(trans);
	}

	private Trans getInsertTransData(EbankPayOrderBusiReq ebankPayBusiReq, Map<String, Object> retMap) {
		
		Trans consumeTrans = new Trans();
		tableNameHelper.generateTableName(consumeTrans, StringUtils.trim(retMap.get(XmlData.ORDERDATE)));// 获取订单表名
		String instId = propertyUtil.getProperty("bsp.instId") ;//机构号
		String tableName = consumeTrans.getTableName();//表名
		String trace = getSequenceHelper.createTraceByInstId(instId, 3, tableName);
		String tradeNo =StringUtils.trim(retMap.get(XmlData.TRADENO));
		String payType =StringUtils.trim(ebankPayBusiReq.getPayType());
		retMap.put(XmlData.INSTID, instId);
		retMap.put(XmlData.TRACE, trace);
		
		consumeTrans.setTrace(trace);
		consumeTrans.setInstId(instId);
		consumeTrans.setPlatDate(TimeUtil.date8());
		consumeTrans.setPlatTime(TimeUtil.time6());
		consumeTrans.setFunCode("P100");
		consumeTrans.setBusiId(DataDict.BUSIID_02);
		consumeTrans.setTradeNo(tradeNo);
		consumeTrans.setPayType(Short.parseShort(payType));
		consumeTrans.setOrderId(StringUtils.trim(retMap.get(XmlData.ORDERID)));
		consumeTrans.setOrderDate(StringUtils.trim(retMap.get(XmlData.ORDERDATE)));
		consumeTrans.setMerId(StringUtils.trim(ebankPayBusiReq.getMerId()));
		try {
			consumeTrans.setInAccount(DES3Util.appEncrypt(StringUtils.trim(retMap.get(XmlData.INACCOUNT))));
		} catch (Exception e) {
			log.error("【网银支付】组织入交易表字段InAccount加解密异常！",e);
			throw new BusinessException(MerBusiEC.PARAM_ENCODE_ERR, "【网银支付】组织入交易表字段InAccount加解密异常！");
		}
		consumeTrans.setInAccountPro(Short.valueOf("3"));
		consumeTrans.setInAccountName(StringUtils.trim(retMap.get(XmlData.MERNAME)));
		consumeTrans.setInMediaId(ebankPayBusiReq.getMerId());
		consumeTrans.setInMediaType(Short.valueOf(DataDict.MEDIATYPE_4));
		//consumeTrans.setOutAccount(StringUtils.trim(reqMap.get(XmlData.BANKACCOUNT)));//网银支付，前端未传入卡号，不记录
		consumeTrans.setOutAccountPro(Short.parseShort(StringUtils.trim(retMap.get(XmlData.OUTACCOUNTPRO))));
		consumeTrans.setOutAccountName(StringUtils.trim(retMap.get(XmlData.OUTACCOUNTNAME)));
		consumeTrans.setOutMediaId(StringUtils.trim(retMap.get(XmlData.OUTMEDIAID)));
		consumeTrans.setOutMediaType(Short.parseShort(DataDict.OUTMEDIATYPE_9));
		//consumeTrans.setBankId();
		//consumeTrans.setPaySeq();
		//consumeTrans.setStlDate();
		//consumeTrans.setStlCheck();
		//consumeTrans.setAccCheckDate();
		consumeTrans.setOrigAmt(Long.parseLong(StringUtils.trim(ebankPayBusiReq.getAmount())));
		consumeTrans.setAmount(Long.parseLong(StringUtils.trim(ebankPayBusiReq.getAmount())));
		consumeTrans.setComAmt(Long.parseLong(StringUtils.trim(retMap.get(XmlData.FEE))));
		consumeTrans.setComAmtType(Short.valueOf(StringUtils.trim(retMap.get(XmlData.COMAMTTYPE))));
		consumeTrans.setAmtType(DataDict.AMTTYPE_01);
		//consumeTrans.setPayType(Short.parseShort(StringUtils.trim(req.getPayType())));
		//consumeTrans.setTranState();
		//consumeTrans.setMerCheck();
		consumeTrans.setPproductId(StringUtils.trim(ebankPayBusiReq.getpProductId()));
		consumeTrans.setBproductId(StringUtils.trim(ebankPayBusiReq.getbProductId()));
		//consumeTrans.setAccountSeq();
		//consumeTrans.setModTime();
		//consumeTrans.setInTime();
		consumeTrans.setMerTrace(StringUtils.trim(ebankPayBusiReq.getMerTrace()));
		consumeTrans.setNotifyUrl(StringUtils.trim(ebankPayBusiReq.getNotifyUrl()));
		consumeTrans.setRetUrl(StringUtils.trim(ebankPayBusiReq.getRetUrl()));
		return consumeTrans;
		
	}

	private void checkOrder(EbankPayOrderBusiReq ebankPayBusiReq, Map<String, Object> retMap) {
		
		Map<String,Object> map = new HashMap<String,Object>();
//		OrderProcess orderProcess = BeanFactory.getOrderProcess(ebankPayBusiReq.getTradeNo());
		map.put(XmlData.AMOUNT, StringUtils.trim(ebankPayBusiReq.getAmount()));
		map.put(XmlData.TRADENO, StringUtils.trim(ebankPayBusiReq.getTradeNo()));
		map.put(XmlData.PAYMENTTYPE, DataDict.PAYTYPE_EBANKPAY);
		map.put(XmlData.SERVICE, DataDict.EBANKPAY_ORDER);
        map.put(XmlData.MERID, StringUtils.trim(ebankPayBusiReq.getMerId()));
//		orderProcess.before(map);
		log.info("【网银支付】原单信息校验通过！");
		retMap.putAll(map);
	}

	private void checkSupportBank(EbankPayOrderBusiReq ebankPayBusiReq) {
		Map<String,String> reqMap = new HashMap<String,String>();
		String pproductId = StringUtils.trim(ebankPayBusiReq.getpProductId());
		String merId = StringUtils.trim(ebankPayBusiReq.getMerId());
		String rpid = StringUtils.trim(ebankPayBusiReq.getRpid());
		String gateId = StringUtils.trim(ebankPayBusiReq.getGateId());
		String binBankId = BankCodeConvertUtil.convertGateId2BinbankId(gateId);
		
		reqMap.put(XmlData.RPID, rpid);
		reqMap.put(XmlData.MERID, merId);
		reqMap.put(XmlData.PPRODUCTID, pproductId);
//		mgrCommonBusiness.qryProductIdSupportCardBin(reqMap);
		String binBankIds = StringUtils.trim(reqMap.get(XmlData.BINBANKIDS));
		if(!binBankIds.contains(binBankId)){
			log.error("【网银支付】不支持的银行卡");
			throw new BusinessException(MerBusiEC.BANKCARD_NOTSUPPORT, "很抱歉，该银行卡不支持网银支付");	
		}
	}

	private void checkMerPproductInfo(EbankPayOrderBusiReq ebankPayBusiReq) {
		
		String rpid = StringUtils.trim(ebankPayBusiReq.getRpid());
		String merId = StringUtils.trim(ebankPayBusiReq.getMerId());
		String pProductId = StringUtils.trim(ebankPayBusiReq.getpProductId());
//		mgrCommonBusiness.verifyMerPProduct(merId, pProductId, rpid);
		log.info(String.format("【网银支付】商户支付产品校验通过！"));
	}

	private void checkMerBproductInfo(EbankPayOrderBusiReq ebankPayBusiReq) {

		// TODO Auto-generated method stub
		String rpid = StringUtils.trim(ebankPayBusiReq.getRpid());
		String merId = StringUtils.trim(ebankPayBusiReq.getMerId());
		String bproductId = StringUtils.trim(ebankPayBusiReq.getbProductId());
		log.info(String.format("校验商户是否开通业务产品，请求参数为:%s，%s", merId,bproductId));
//		mgrCommonBusiness.vefiryMerBProduct(merId, bproductId, rpid);
		log.info("【网银支付】商户业务产品校验通过！");
	}

	private void checkMerSettleAccState(EbankPayOrderBusiReq ebankPayBusiReq, Map<String, Object> retMap) {
		Map<String,Object> map = new HashMap<String,Object>();
//		OrderProcess orderProcess = BeanFactory.getOrderProcess(ebankPayBusiReq.getTradeNo());
		
		map.put(XmlData.RPID, StringUtils.trim(ebankPayBusiReq.getRpid()));//流水号
		map.put(XmlData.MERID, StringUtils.trim(ebankPayBusiReq.getMerId()));//商户号
		map.put(XmlData.ACTORID, StringUtils.trim(ebankPayBusiReq.getMerId()));//参与者号
		map.put(XmlData.ACTORTYPE, DataDict.USER_ACC_TYPE_2);//设置参与者类型(所有用户开的都为对公账户)
		map.put(XmlData.ACCTYPE, DataDict.ACCOUNT_TYPE_1);//设置账户类型
		map.put(XmlData.PAYMENTTYPE, DataDict.PAYTYPE_EBANKPAY);
		map.put(XmlData.SERVICE, DataDict.EBANKPAY_ORDER);
//		orderProcess.init(map);
		retMap.put(XmlData.INACCOUNT, map.get(XmlData.INACCOUNT));
		log.info("【网银支付】商户信息校验通过！");
	}

	private void checkMerInfoAndState(EbankPayOrderBusiReq ebankPayBusiReq, Map<String, Object> retMap) {
		Map<String,String> reqMap= new HashMap<String,String>();
		reqMap.put(XmlData.RPID, StringUtils.trim(ebankPayBusiReq.getRpid()));//流水号
		reqMap.put(XmlData.MERID, StringUtils.trim(ebankPayBusiReq.getMerId()));//商户号
		reqMap.put(XmlData.ACTORID, StringUtils.trim(ebankPayBusiReq.getMerId()));//参与者号
		reqMap.put(XmlData.ACTORTYPE, DataDict.USER_ACC_TYPE_2);//设置参与者类型(所有用户开的都为对公账户)
		reqMap.put(XmlData.ACCTYPE, DataDict.ACCOUNT_TYPE_1);//设置账户类型
//		mgrCommonBusiness.verifyMerInfo(reqMap);
		log.info("【网银支付】商户信息校验通过！");
		retMap.put(XmlData.MERNAME, StringUtils.trim(reqMap.get(XmlData.MERNAME)));
	}
}
